"""
@File    :   route_depend.py
@Time    :   2024/03/28 23:35:28
@Author  :   Qrj
@Email   :   923207736@qq.com
@description   :   路由依赖(用于维持本业务的路由部分整洁)
"""


from typing import Annotated

from fastapi import Depends, Query
from pydantic import HttpUrl
from redis.asyncio import Redis
from sqlalchemy.ext.asyncio import AsyncSession

from src.business.admin.system.oauth2.auth.authorization_code.schemas.out import (
    AuthorizationCodeCompleteOutSchema,
)
from src.business.admin.system.oauth2.auth.authorization_code.schemas.validate import (
    AuthorizationCodeCreateDoubleTokenValidateSchema,
    AuthorizationCodeCreateValidateSchema,
)
from src.business.admin.system.oauth2.auth.authorization_code.service import (
    AuthorizationCodeService,
)
from src.business.admin.system.oauth2.auth.enums import OAuth2GrantTypeEnum
from src.business.admin.system.oauth2.client.dependencies.introduction import (
    ValidateOAuth2ClientExistsDependencies,
)
from src.business.admin.system.oauth2.client.schemas.out import (
    Oauth2ClientCompleteOutSchema,
)
from src.business.admin.system.oauth2.client.service import Oauth2ClientService
from src.business.admin.system.oauth2.token.schemas.out import (
    DoubleTokenCompleteOutSchema,
)
from src.business.admin.system.tenant.tenant.dependencies.no_introduction import (
    ValidateTenantExistsDependencies,
)
from src.business.admin.system.tenant.tenant.schemas.out import TenantCompleteOutSchema
from src.dependencies.no_introduction import (
    depend_get_master_db_session,
    depend_get_token_redis_pool,
)


class RouteDependGetCodeLoginPage:
    """获取授权码的用户登录页面的依赖类"""

    def __init__(self):
        self.tenant: TenantCompleteOutSchema | None = None
        self.oauth2_client: Oauth2ClientCompleteOutSchema | None = None
        self.redirect_uri: HttpUrl | None = None
        self.state: str | None = None

    async def __call__(
        self,
        tenant: Annotated[
            TenantCompleteOutSchema,
            Depends(ValidateTenantExistsDependencies.from_query),
        ],
        oauth2_client: Annotated[
            Oauth2ClientCompleteOutSchema,
            Depends(ValidateOAuth2ClientExistsDependencies.from_query),
        ],
        redirect_uri: HttpUrl = Query(default=..., description="重定向url"),
        state: str = Query(
            default=..., min_length=1, max_length=200, description="客户端状态"
        ),
    ) -> "RouteDependGetCodeLoginPage":
        # 验证是否允许客户端使用当前授权模式
        Oauth2ClientService.validate_oauth2_client_authorized_grant_type(
            oauth2_client.authorized_grant_types, OAuth2GrantTypeEnum.authorization_code
        )
        # 验证客户端的重定向uri是否在允许的可重定向的URI地址列表内
        Oauth2ClientService.validate_oauth2_client_redirect_uri(
            oauth2_client.redirect_uris, redirect_uri
        )
        self.tenant = tenant
        self.oauth2_client = oauth2_client
        self.redirect_uri = redirect_uri
        self.state = state
        return self


# 实例化获取授权码的用户登录页面的依赖类
route_depend_get_code_login_page = RouteDependGetCodeLoginPage()


async def route_depened_create_authorization_code(
    create_schema: AuthorizationCodeCreateValidateSchema,
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
) -> AuthorizationCodeCompleteOutSchema:
    """创建授权码模式的授权码的依赖(授权码模式将code重定向给重定向uri时使用)
    作为路由的共用逻辑抽象(因为路由分为无验证码、图像验证码、行为验证码等)

    Args:
        create_schema (AuthorizationCodeCreateValidateSchema): 创建所需的参数
        db_session (Annotated[AsyncSession, Depends): _descri数据库连接池ption_

    Returns:
        AuthorizationCodeCompleteOutSchema: 授权码数据
    """
    # 创建授权码数据
    auth_code_data = await AuthorizationCodeService.create_authorization_code(
        db_session, create_schema
    )
    return auth_code_data


async def route_depend_authorization_code_create_double_token(
    create_schema: AuthorizationCodeCreateDoubleTokenValidateSchema,
    db_session: Annotated[AsyncSession, Depends(depend_get_master_db_session)],
    token_redis_pool: Annotated[Redis, Depends(depend_get_token_redis_pool)],
) -> DoubleTokenCompleteOutSchema:
    """创建Oauth2授权码模式的双Token的路由依赖

    Args:
        create_schema (AuthorizationCodeCreateDoubleTokenValidateSchema): 创建所需参数
        db_session (Annotated[AsyncSession, Depends): 数据库连接池
        token_redis_pool (Annotated[Redis, Depends): token的redis连接池

    Returns:
        DoubleTokenCompleteOutSchema: 双Token信息
    """
    double_token = (
        await AuthorizationCodeService.create_authorization_code_double_token(
            db_session, token_redis_pool, create_schema
        )
    )
    return double_token
